package cn.lijiguo.concurrency.threadpool;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <pre>newSingleThreadExecutor</pre>
 *  <p>
 *      用于创建一个包含单个线程的线程池。
 *      这个线程确保所有提交的任务按照顺序执行，即每次只有一个线程在执行任务
 *      如果这个线程因异常而结束，会有另一个线程取代它，保持线程池中始终存在一个活动线程
 *      这种线程池适用于需要按顺序执行任务的场景，且在任务执行期间不需要并发执行。
 *  </p>
 *  <p>使用 newSingleThreadExecutor 创建单线程池的主要优势在于对任务的顺序执行以及异常处理的管理。
 *  以下是一些使用单线程池的优势：</p>
 *  <li>顺序执行，单线程池保证任务按照提交的顺序执行</li>
 *  <li>线程复用，线程池中只有一个线程，该线程会被重复使用来执行不同的任务。
 *      这减少了线程的创建和销毁开销，提高了线程的复用性。</li>
 *  <li>异常管理，如果任务抛出异常而导致线程终止，单线程池会创建一个新的线程来取代原来的线程，
 *      确保线程池中总是有一个可用的线程，防止因为异常而导致整个应用程序崩溃</li>
 *  <li>方便的线程控制，单线程池通过一个线程来处理任务，使得在某些场景下更容易进行线程控制和调试。
 *      例如，你可以更容易地追踪任务的执行，查看任务的日志，进行线程调试等。</li>
 *  <li>任务队列的管理，单线程池内部维护了一个任务队列，将任务按照提交的顺序进行排队。
 *      这有助于管理任务的执行顺序和控制任务的并发度。</li>
 * @author lijiguo
 */
@Slf4j
public class SingleThreadExecutorDemo {

    public static void main(String[] args) {
        // 创建一个单个线程的线程池
        ExecutorService executorService = Executors.newSingleThreadExecutor();

        // 执行任务
        for (int i = 0; i < 5; i++) {
            final int taskId = i;
            executorService.submit(() -> {
                log.info("Task " + taskId + " is executing by " + Thread.currentThread().getName());
                try {
                    // 模拟任务执行
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    log.error(e.getMessage(), e);
                    Thread.currentThread().interrupt();
                }
            });
        }

        // 关闭线程池
        executorService.shutdown();
    }
}
